/******************************************************************************
** 
** File name:	UTEST_10.c
**	
** Description: RTOS Unit Tests. Basic Task/ISR Management Tests. 
**				- Single level interrupt processing. 
**				- Single interrupt source.
**				- No nested interrupts.
**
** RTOS API functions to be tested:
**		
**	- rtos_task_resume_isr();
**
** Note:		none
**
*******************************************************************************
** Change history:
**	
** 07/10/2011 - AK - File created. 
** 19/03/2012 - AK - Adopted for AVR Studio V5.1. 
** 
******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rtos.h"
#include "utest.h"

/******************************************************************************
**	RTOS DECLARARTION SECTION
**
**  Standard config for RTOS task functionality testing.
**
**	Timer interrupt #1:			SYSTEM_TimerHandler (defined by USER)
**	Timer interrupt #2:			USER_TimerHandler_1 (defined by USER)
**	Timer interrupt #3:			USER_TimerHandler_2 (defined by USER)
**
**	Timers:						n/a
**	Events:						n/a
**	Messages:					n/a			
**	Queues:						n/a			
**	Timers:						n/a
**	
**	Three tasks:				tsk0,		tsk1,		tsk2,		tsk3 
**  Three priorities:			0(highest)	1 (high)	2 (middle)	3 (low)
**  Stack size:					8			20			20			20
**
**  Notes:						Either SYSTEM_TimerHandler or tsk0 is only 
**								for stack overflow control!!!
**
******************************************************************************/

RTOS_DECLARE_ISR(SYSTEM_TIMER_VECTOR,SYSTEM_TimerHandler);
RTOS_DECLARE_ISR(USER_TIMER_1_VECTOR,USER_TimerHandler_1);
RTOS_DECLARE_ISR(USER_TIMER_2_VECTOR,USER_TimerHandler_2);

RTOS_DECLARE_TASK(tsk0,  8, 0);
RTOS_DECLARE_TASK(tsk1, 20, 1);
RTOS_DECLARE_TASK(tsk2, 20, 2);
RTOS_DECLARE_TASK(tsk3, 20, 3);

/******************************************************************************
** Timer Hardware Configuration Section
******************************************************************************/
UTST_TIMER_t	sys_tmr = 
{
	&(SYSTEM_TIMER),
	20000,
	LEVEL_HIGH,
	STATE_STOP
};

UTST_TIMER_t	usr_tmr_1 =
{
	&(USER_TIMER_1),
	10010,
	LEVEL_MED,
	STATE_STOP
};

UTST_TIMER_t	usr_tmr_2 =
{
	&(USER_TIMER_2),
	5005,
	LEVEL_LOW,
	STATE_STOP
};


/******************************************************************************
	UNIT TEST MAIN FUNCTION
******************************************************************************/
int main(void)
{
	// RTOS kernel initialization
    rtos_initialize_os(0);

	// UTEST peripheral modules initialization (HW depended)

	// Timer-counters initialization (interrupt sources)
	utst_init_timer(&usr_tmr_1);
	utst_init_timer(&usr_tmr_2);
	utst_init_timer(&sys_tmr);

	// Interrupt controller initialization
	utst_init_pmic();

	// RTOS task initialization 	
    rtos_task_init_exp (tsk0);	// Init but not start 
    rtos_task_start_exp(tsk1);
    rtos_task_start_exp(tsk2);
    rtos_task_start_exp(tsk3);
	
	// UTEST timers start
	UTST_TIMER_START(SYSTEM_TIMER);
	UTST_TIMER_START(USER_TIMER_1);
	UTST_TIMER_START(USER_TIMER_2);

	rtos_start_os();
	
	return 1;
}

/******************************************************************************
	UNIT TEST INTERRUPT FUNCTION[s]
******************************************************************************/
static volatile uint8_t TimerCounter = 0;

RTOS_ISR_FUNC(SYSTEM_TimerHandler)
{
		// Check task' stacks consistency
		rtos_stack_check(tsk0);
		rtos_stack_check(tsk1);
		rtos_stack_check(tsk2);
		rtos_stack_check(tsk3);	
}


RTOS_ISR_FUNC(USER_TimerHandler_1)
{
	if ( TimerCounter == 1 )
	{
		rtos_task_resume_isr(&tsk1PID);	
	}
	if ( TimerCounter == 2 )
	{
		rtos_task_resume_isr(&tsk2PID);	
	}
	if ( TimerCounter == 3 )
	{
		rtos_task_resume_isr(&tsk3PID);	
	}
	TimerCounter += (TimerCounter < 3) ? 1 : -3;
}

RTOS_ISR_FUNC(USER_TimerHandler_2)
{
}

/******************************************************************************
	UNIT TEST TASK FUNCTIONs
******************************************************************************/

/* RTOS Task #0 */
RTOS_TASK_FUNC(tsk0)
{
	while (1)
	{
		rtos_stack_check(tsk0);
		rtos_stack_check(tsk1);
		rtos_stack_check(tsk2);
		rtos_stack_check(tsk3);
		rtos_task_suspend(&tsk0PID);
	}
}


/* RTOS Task #1 */
RTOS_TASK_FUNC(tsk1)
{
	while(1)
	{
		rtos_task_suspend(&tsk1PID);
	}
}

/* RTOS Task #2 */
RTOS_TASK_FUNC(tsk2)
{
	while(1)
	{
		rtos_task_suspend(&tsk2PID);		
	}
}

/* RTOS Task #3 */
RTOS_TASK_FUNC(tsk3)
{
	while(1)
	{
		rtos_task_suspend(&tsk3PID);		
	}
}

